package com.lagou.zk;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * 封装了部分常用方法，如果不够用也可以通过getClient获取zkClient直接操作
 */
@Component
public class ZookeeperClient {

    private static CuratorFramework client;

    @Value("${zk.ip.port}")
    private String ipPort;

    @Value("${zk.timeout.session}")
    private int sessionTimeOut;

    @Value("${zk.timeout.connection}")
    private int connectionTimeOut;

    @Value("${zk.namespace}")
    private String namespace;

    @PostConstruct
    private void init () {
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
        client = CuratorFrameworkFactory.builder().connectString(ipPort).sessionTimeoutMs(sessionTimeOut)
                .connectionTimeoutMs(connectionTimeOut).retryPolicy(retryPolicy).namespace(namespace).build();
        client.start();
    }

    public static CuratorFramework getClient() {
        return client;
    }

    public String creatPath(String path) throws Exception {
        return creatPath(path, null, CreateMode.PERSISTENT);
    }

    public String creatPath(String path, String value) throws Exception {
        return creatPath(path, value, CreateMode.PERSISTENT);
    }

    public String creatTempPath(String path) throws Exception {
        return creatPath(path, null, CreateMode.EPHEMERAL);
    }

    public String creatTempPath(String path, String value) throws Exception {
        return creatPath(path, value, CreateMode.EPHEMERAL);
    }

    public String createSEQPath(String path) throws Exception {
        return creatPath(path, null, CreateMode.PERSISTENT_SEQUENTIAL);
    }

    public String createSEQPath(String path, String value) throws Exception {
        return creatPath(path, value, CreateMode.PERSISTENT_SEQUENTIAL);
    }

    public String createSEQTempPath(String path) throws Exception {
        return creatPath(path, null, CreateMode.EPHEMERAL_SEQUENTIAL);
    }

    public String createSEQTempPath(String path, String value) throws Exception {
        return creatPath(path, value, CreateMode.EPHEMERAL_SEQUENTIAL);
    }

    public String creatPath(String path, String value, CreateMode createMode) throws Exception {
        if (path == null) {
            throw new RuntimeException("Path 不能为空");
        }
        if (isExist(path)) {
            System.out.println("该节点已经存在Path：" + path);
            return null;
        }
        return client.create().creatingParentsIfNeeded().
                withMode(createMode).forPath(path, value == null ? null : value.getBytes());

    }

    public void deletePath(String path) throws Exception {
        if (isExist(path)) {
            client.delete().deletingChildrenIfNeeded().forPath(path);
        }
    }

    public boolean isExist(String path) throws Exception {
        if (path == null) {
            throw new RuntimeException("Path 不能为空");
        }

        return client.checkExists().forPath(path) != null;
    }


}
